﻿//===============================================================================
// Microsoft Innovation Centre - Western Europe
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.WVB.Framework;
using Microsoft.WVB.Silverlight.Infrastructure;
using System.Diagnostics;

namespace Microsoft.WVB.UI
{
    [TemplatePart(Name= BStateUIButton.AnonymousElementName, Type = typeof(ContentPresenter)),
    TemplatePart(Name = BStateUIButton.AuthenticatedElementName, Type = typeof(ContentPresenter))]
    [TemplateVisualState(GroupName = VisualStates.GroupAuthentication, Name = VisualStates.StateAnonymous),
    TemplateVisualState(GroupName = VisualStates.GroupAuthentication, Name = VisualStates.StateAuthenticated)]
    public class BStateUIButton: Button
    {
        private const string AnonymousElementName = "AnonymousElement";
        private const string AuthenticatedElementName = "AuthenticatedElement";

        internal ContentPresenter AuthenticatedElement { get; set; }
        internal ContentPresenter AnonymousElement { get; set; }

        public static readonly DependencyProperty IsUserAuthenticatedProperty = null;
        public static readonly DependencyProperty AnonymousContentProperty = null;
        public static readonly DependencyProperty AnonymousTemplateProperty = null;

        public IUserManager ViewModel { get; set; }

        public Object AnonymousContent
        {
            get { return (Object)GetValue(AnonymousContentProperty); }
            set { SetValue(AnonymousContentProperty, value); }
        }

        public Boolean IsUserAuthenticated
        {
            get { return (Boolean)GetValue(IsUserAuthenticatedProperty); }
            set { SetValue(IsUserAuthenticatedProperty, value); }
        }

        public DataTemplate AnonymousTemplate
        {
            get { return (DataTemplate)GetValue(AnonymousTemplateProperty); }
            set { SetValue(AnonymousTemplateProperty, value); }
        }

        public BStateUIButton()
            : base()
        {
            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                ViewModel = IoC.GetCreate<IUserManager>();
                DataContext = ViewModel;

                Binding b = new Binding("IsAuthenticated");
                b.Mode = BindingMode.OneWay;
                b.Source = ViewModel;
                this.SetBinding(IsUserAuthenticatedProperty, b);
            }                 
        }

        static BStateUIButton()
        {
            AnonymousTemplateProperty = DependencyProperty.Register("AnonymousTemplate", typeof(DataTemplate), typeof(BStateUIButton), new PropertyMetadata(new PropertyChangedCallback(OnAnonymousTemplateChanged)));
            AnonymousContentProperty = DependencyProperty.Register("AnonymousContent", typeof(Object), typeof(BStateUIButton), new PropertyMetadata(new PropertyChangedCallback(OnAnonymousContentChanged)));
            IsUserAuthenticatedProperty = DependencyProperty.Register("IsUserAuthenticated", typeof(Boolean), typeof(BStateUIButton), new PropertyMetadata(new PropertyChangedCallback(OnIsUserAuthenticatedChanged)));
        }

        
        public override void OnApplyTemplate()
        {            
            base.OnApplyTemplate();

            this.AnonymousElement = base.GetTemplateChild(BStateUIButton.AnonymousElementName) as ContentPresenter;
            this.AuthenticatedElement = base.GetTemplateChild(BStateUIButton.AuthenticatedElementName) as ContentPresenter;
            
            if (this.AnonymousElement != null)
            {
                if (this.AnonymousTemplate != null)
                {
                    this.OnAnonymousTemplateChanged(null, this.AnonymousTemplate);
                }
                else
                {
                    this.OnAnonymousContentChanged(null, this.AnonymousContent);
                }
            }

            this.UpdateVisualState();
        }

        static void OnIsUserAuthenticatedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((BStateUIButton)d).OnIsUserAuthenticatedChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        protected virtual void OnIsUserAuthenticatedChanged(bool OldValue, bool newValue)
        {
            UpdateVisualState();
        }

        static void OnAnonymousContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((BStateUIButton)d).OnAnonymousContentChanged(e.OldValue, e.NewValue);
        }

        static void OnAnonymousTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((BStateUIButton)d).OnAnonymousTemplateChanged((DataTemplate) e.OldValue, (DataTemplate)e.NewValue);
        }

        protected virtual void OnAnonymousContentChanged(object oldValue, object newValue)
        {
            if ((AnonymousTemplate == null) && (this.AnonymousElement != null))
            {
                this.AnonymousElement.Content = newValue;
            }
        }

        protected virtual void OnAnonymousTemplateChanged(DataTemplate oldTemplate, DataTemplate newTemplate)
        {
            if (this.AnonymousElement != null)
            {
                if (AnonymousTemplate == null)
                {
                    this.AnonymousElement.Content = this.AnonymousContent;
                }
                else
                {
                    FrameworkElement element = this.AnonymousTemplate.LoadContent() as FrameworkElement;
                    this.AnonymousElement.Content = element;
                }
            }
        }

        internal void UpdateVisualState()
        {
            this.ChangeVisualState(false);
        }

        private void ChangeVisualState(bool useTransitions)
        {
            if (this.IsUserAuthenticated)
            {
                VisualStates.GoToState(this, useTransitions, new String[] { VisualStates.StateAuthenticated });
#if TRACEDEBUG

                Debug.WriteLine(this.IsUserAuthenticated);
#endif 
            }

            else 
            {
                VisualStates.GoToState(this, useTransitions, new String[] { VisualStates.StateAnonymous });
#if TRACEDEBUG

                Debug.WriteLine(this.IsUserAuthenticated);
#endif
            }
        }
    }
}
